package ${package}.${rootArtifactId}.common.util;


import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * HTTP工具类
 *
 * @author weidong.lin
 * @date 2021/7/8 11:06
 */
public class HttpUtil {
    private static CloseableHttpClient httpclient;

    static {
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
                new PoolingHttpClientConnectionManager();
        poolingHttpClientConnectionManager.setMaxTotal(200);
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(20);

        // 根据默认超时限制初始化requestConfig
        int socketTimeout = 30000;
        int connectTimeout = 10000;
        int connectionRequestTimeout = 10000;
        RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(
                connectionRequestTimeout).setSocketTimeout(socketTimeout).setConnectTimeout(
                connectTimeout).build();

        httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig).
                evictIdleConnections(600, TimeUnit.SECONDS)
                .setConnectionManager(poolingHttpClientConnectionManager)
                .build();

    }

    private HttpUtil() {
    }

    /**
     * get请求，url带参数
     *
     * @param uri
     * @param <T>
     * @return
     */
    public static <T> T doGet(String uri, TypeReference responseTypeRef) throws IOException {
        // 创建httpget
        HttpGet httpGet = new HttpGet(uri);
        ObjectMapper mapper = new ObjectMapper();

        HttpResponse res = httpclient.execute(httpGet);
        return getResponse(mapper, res, responseTypeRef);
    }

    /**
     * post请求
     *
     * @param uri
     * @param request
     * @param <T>
     * @return
     */
    public static <T> T doPost(String uri, Object request, TypeReference responseTypeRef) throws IOException {
        // 创建httppost
        HttpPost httppost = new HttpPost(uri);

        // 创建参数队列
        ObjectMapper mapper = new ObjectMapper();
        if (request != null) {
            String requestData = null;
            if (request instanceof String) {
                requestData = (String) request;
            } else {
                requestData = mapper.writeValueAsString(request);
            }
            httppost.setEntity(new StringEntity(requestData, ContentType.APPLICATION_JSON));
        }

        HttpResponse res = httpclient.execute(httppost);
        return getResponse(mapper, res, responseTypeRef);

    }

    private static <T> T getResponse(ObjectMapper mapper, HttpResponse res, TypeReference responseTypeRef)
            throws IOException {
        HttpEntity entity = res.getEntity();
        String responseString = EntityUtils.toString(entity);
        EntityUtils.consume(entity);
        if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            return (T) mapper.readValue(responseString, responseTypeRef);
        } else {
            throw new RuntimeException("HTTP CODE =" + res.getStatusLine().getStatusCode());
        }
    }


}
